Spring Security অ্যাপ্লিকেশনে Role-Based Authorization এবং Permission-Based Authorization কনফিগার করার একটি শক্তিশালী পদ্ধতি প্রদান করে।
1. Role-Based Authorization
Role-Based Authorization-এ ব্যবহারকারীকে নির্দিষ্ট "রোল" দেওয়া হয়। সেই রোলের উপর ভিত্তি করে অ্যাপ্লিকেশনের নির্দিষ্ট অংশে (এন্ডপয়েন্ট বা ফিচার) অ্যাক্সেস কন্ট্রোল করা হয়। উদাহরণস্বরূপ, ADMIN এবং USER রোল থাকতে পারে, যেখানে ADMIN রোল ব্যবহারকারী প্রশাসনিক ফিচার অ্যাক্সেস করতে পারবে।
Role-Based Authorization উদাহরণ
Step 1: Maven ডিপেনডেন্সি
Spring Security ব্যবহার করতে spring-boot-starter-security ডিপেনডেন্সি যোগ করুন।
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Step 2: Security Configuration
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // ADMIN রোলের জন্য
.antMatchers("/user/**").hasRole("USER") // USER রোলের জন্য
.anyRequest().authenticated() // বাকি সব অথেন্টিকেশন চায়
.and()
.formLogin()
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("admin123")).roles("ADMIN")
.and()
.withUser("user").password(passwordEncoder().encode("user123")).roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Step 3: REST Controller তৈরি
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/admin/dashboard")
public String adminDashboard() {
return "Welcome to Admin Dashboard!";
}
@GetMapping("/user/profile")
public String userProfile() {
return "Welcome to User Profile!";
}
}
Testing:
/admin/dashboardঅ্যাক্সেস করতেadminক্রিডেনশিয়াল প্রয়োজন।/user/profileঅ্যাক্সেস করতেuserক্রিডেনশিয়াল প্রয়োজন।
2. Permission-Based Authorization
Permission-Based Authorization-এ, নির্দিষ্ট অনুমতি (permissions) সেটআপ করা হয়, এবং ব্যবহারকারীকে নির্দিষ্ট কাজ করার অনুমতি প্রদান করা হয়। উদাহরণস্বরূপ, WRITE_PRIVILEGE এবং READ_PRIVILEGE থাকতে পারে, যা ব্যবহারকারীর কার্যকলাপ নিয়ন্ত্রণ করে।
Permission-Based Authorization বাস্তবায়ন
Step 1: Role এবং Permission Mapping
Role এবং Permission এর মধ্যে সম্পর্ক সেটআপ করতে আপনাকে কাস্টম সলিউশন প্রয়োজন।
import java.util.Set;
public class Role {
private String name;
private Set<Permission> permissions;
public Role(String name, Set<Permission> permissions) {
this.name = name;
this.permissions = permissions;
}
public String getName() {
return name;
}
public Set<Permission> getPermissions() {
return permissions;
}
}
public class Permission {
private String name;
public Permission(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Step 2: Custom UserDetailsService
Custom UserDetailsService ব্যবহার করে ব্যবহারকারীর রোল এবং পারমিশন সেট করুন।
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username.equals("admin")) {
return new User("admin", new BCryptPasswordEncoder().encode("admin123"), getAuthorities("ADMIN"));
} else if (username.equals("user")) {
return new User("user", new BCryptPasswordEncoder().encode("user123"), getAuthorities("USER"));
}
throw new UsernameNotFoundException("User not found!");
}
private Collection<? extends GrantedAuthority> getAuthorities(String role) {
List<GrantedAuthority> authorities = new ArrayList<>();
if (role.equals("ADMIN")) {
authorities.add(new SimpleGrantedAuthority("WRITE_PRIVILEGE"));
authorities.add(new SimpleGrantedAuthority("READ_PRIVILEGE"));
} else if (role.equals("USER")) {
authorities.add(new SimpleGrantedAuthority("READ_PRIVILEGE"));
}
return authorities;
}
}
Step 3: Security Configuration
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/write").hasAuthority("WRITE_PRIVILEGE") // WRITE_PRIVILEGE প্রয়োজন
.antMatchers("/read").hasAuthority("READ_PRIVILEGE") // READ_PRIVILEGE প্রয়োজন
.anyRequest().authenticated()
.and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
}
Step 4: REST Controller তৈরি
@RestController
@RequestMapping("/permissions")
public class PermissionController {
@GetMapping("/read")
public String readPermission() {
return "You have READ permission!";
}
@GetMapping("/write")
public String writePermission() {
return "You have WRITE permission!";
}
}
Testing:
/permissions/readঅ্যাক্সেস করতেREAD_PRIVILEGEপ্রয়োজন।/permissions/writeঅ্যাক্সেস করতেWRITE_PRIVILEGEপ্রয়োজন।
Role-Based vs Permission-Based Authorization
| Features | Role-Based Authorization | Permission-Based Authorization |
|---|---|---|
| Granularity | সাধারণত রোল লেভেলে সীমাবদ্ধ। | ফাইন-গ্রেইনড কন্ট্রোল প্রদান করে। |
| Flexibility | তুলনামূলকভাবে কম। | বেশি। |
| Use Case | সাধারণ অ্যাপ্লিকেশনের জন্য। | অ্যাপ্লিকেশনে আরও জটিল অ্যাক্সেস কন্ট্রোল দরকার হলে। |
উপসংহার
Spring Security-তে Role-Based Authorization সাধারণ অথেন্টিকেশন ব্যবহারের জন্য সহজ এবং কার্যকর। তবে আরও উন্নত এবং নির্দিষ্ট কন্ট্রোলের জন্য Permission-Based Authorization ব্যবহার করা হয়। বাস্তব অ্যাপ্লিকেশনে উভয় পদ্ধতির সংমিশ্রণ ব্যবহার করলে আরও শক্তিশালী নিরাপত্তা ব্যবস্থা তৈরি করা যায়।
Role-Based Authorization হলো Spring Security-এর একটি পদ্ধতি যেখানে ব্যবহারকারীর অনুমতি (Authorization) নির্ধারণ করা হয় তাদের Role এর উপর ভিত্তি করে। একটি Role মূলত অ্যাপ্লিকেশনের ভেতরে নির্ধারিত কিছু অনুমতির একটি সেট, যা ব্যবহারকারীর নির্দিষ্ট রিসোর্স বা কার্যক্রমে অ্যাক্সেসের অধিকার দেয়।
উদাহরণস্বরূপ:
- USER রোলের অধিকারী ব্যবহারকারীরা সাধারণ ফিচার অ্যাক্সেস করতে পারে।
- ADMIN রোলের অধিকারী ব্যবহারকারীরা অ্যাডমিন প্যানেল এবং উন্নত ফিচারগুলোতে অ্যাক্সেস করতে পারে।
Role-Based Authorization-এর সুবিধা
- সহজ ব্যবস্থাপনা:
- ব্যবহারকারীর অনুমতি সরাসরি রোলের মাধ্যমে পরিচালনা করা সহজ।
- স্কেলযোগ্যতা:
- বড় অ্যাপ্লিকেশনগুলোর জন্য রোল-ভিত্তিক সিস্টেম স্কেল করা সহজ।
- পুনঃব্যবহারযোগ্যতা:
- একাধিক রিসোর্সের জন্য একই রোল ব্যবহার করা যায়।
- নিরাপত্তা বৃদ্ধি:
- স্পষ্টভাবে সংজ্ঞায়িত রোল এবং অনুমতির মাধ্যমে অ্যাপ্লিকেশনকে সুরক্ষিত রাখা যায়।
Spring Security-তে Role-Based Authorization এর প্রয়োগ
1. ডিপেন্ডেন্সি যোগ করা
Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Gradle:
implementation 'org.springframework.boot:spring-boot-starter-security'
2. ইন-মেমরি রোল ভিত্তিক ইউজার ডিফাইন করা
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Password encoding
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/user/**").hasRole("USER") // USER রোলের জন্য
.antMatchers("/admin/**").hasRole("ADMIN") // ADMIN রোলের জন্য
.anyRequest().authenticated() // অন্য সবকিছুর জন্য অথেন্টিকেশন প্রয়োজন
.and()
.formLogin() // ফর্ম ভিত্তিক লগইন সক্রিয়
.and()
.logout(); // লগআউট সক্রিয়
}
}
3. রোল ভিত্তিক অনুমোদনের জন্য অ্যানোটেশন ব্যবহার
Spring Security-তে রোল ভিত্তিক অথরাইজেশনের জন্য @PreAuthorize বা @Secured অ্যানোটেশন ব্যবহার করা যায়।
@PreAuthorize ব্যবহার:
@RestController
@RequestMapping("/api")
public class RoleBasedController {
@GetMapping("/user")
@PreAuthorize("hasRole('USER')")
public String userAccess() {
return "Welcome, USER!";
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String adminAccess() {
return "Welcome, ADMIN!";
}
}
@Secured ব্যবহার:
@RestController
@RequestMapping("/api")
public class RoleBasedController {
@GetMapping("/user")
@Secured("ROLE_USER")
public String userAccess() {
return "Welcome, USER!";
}
@GetMapping("/admin")
@Secured("ROLE_ADMIN")
public String adminAccess() {
return "Welcome, ADMIN!";
}
}
মনে রাখুন:
@Securedব্যবহারের ক্ষেত্রে ROLE_ প্রিফিক্স প্রয়োজন।@PreAuthorizeব্যবহার করলে ROLE_ প্রিফিক্স দরকার হয় না।
4. ডাটাবেস ভিত্তিক রোল ব্যবস্থাপনা
ডাটাবেস থেকে ইউজার এবং রোল লোড করার জন্য UserDetailsService ব্যবহার করা হয়।
ডাটাবেস টেবিল কাঠামো:
CREATE TABLE users (
username VARCHAR(50) PRIMARY KEY,
password VARCHAR(100) NOT NULL,
enabled BOOLEAN NOT NULL
);
CREATE TABLE roles (
id INT PRIMARY KEY AUTO_INCREMENT,
role_name VARCHAR(50) NOT NULL
);
CREATE TABLE user_roles (
username VARCHAR(50),
role_id INT,
FOREIGN KEY (username) REFERENCES users(username),
FOREIGN KEY (role_id) REFERENCES roles(id)
);
কনফিগারেশন:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username = ?")
.authoritiesByUsernameQuery("SELECT u.username, r.role_name FROM user_roles ur " +
"JOIN users u ON ur.username = u.username " +
"JOIN roles r ON ur.role_id = r.id WHERE u.username = ?");
}
উদাহরণ API
রোল ভিত্তিক URL অ্যাক্সেস:
@RestController
@RequestMapping("/api")
public class RoleBasedController {
@GetMapping("/user")
public String userAccess() {
return "User content";
}
@GetMapping("/admin")
public String adminAccess() {
return "Admin content";
}
@GetMapping("/all")
public String allAccess() {
return "Public content";
}
}
কনফিগারেশন:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/all").permitAll() // Public access
.antMatchers("/api/user").hasRole("USER") // USER role required
.antMatchers("/api/admin").hasRole("ADMIN") // ADMIN role required
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout();
}
উপসংহার
Role-Based Authorization একটি জনপ্রিয় এবং কার্যকর পদ্ধতি যা ব্যবহারকারীর অ্যাক্সেস কন্ট্রোল ম্যানেজ করতে সাহায্য করে। Spring Security-তে এটি সহজে বাস্তবায়ন করা যায় এবং ইন-মেমরি বা ডাটাবেস উভয় ক্ষেত্রেই সমর্থন প্রদান করে। এটি বড় অ্যাপ্লিকেশনগুলিতে নিরাপত্তা নিশ্চিত করার জন্য অত্যন্ত গুরুত্বপূর্ণ।
Spring Security-তে Authorization পরিচালনা করতে @PreAuthorize এবং @Secured অ্যানোটেশন ব্যবহার করা হয়। এগুলো মেথড-লেভেল অথোরাইজেশনের জন্য ব্যবহৃত হয়। এর মাধ্যমে নির্ধারণ করা হয় কোন ব্যবহারকারী বা রোল নির্দিষ্ট মেথড অ্যাক্সেস করতে পারবে।
@PreAuthorize এবং @Secured এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | @PreAuthorize | @Secured |
|---|---|---|
| অধিকরণ | Spring Security Expression ব্যবহার করে। | শুধুমাত্র রোল ভিত্তিক। |
| সাপোর্ট | জটিল স্পেলিং সমর্থন করে (e.g., hasRole, hasAuthority, @annotation). | সহজ অথোরাইজেশন সমর্থন করে। |
| ব্যবহার ক্ষেত্র | মেথড লেভেল অথোরাইজেশনের জন্য। | সরাসরি রোল চেক করার জন্য। |
1. @PreAuthorize ব্যবহার করা
@PreAuthorize Spring Security-এর স্পেলিং ভাষা ব্যবহার করে অথোরাইজেশন পরিচালনা করে। এটি মেথড চালানোর আগে চেক করে।
কনফিগারেশন
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
// No specific method-level security configuration needed.
}
মেথড উদাহরণ
import org.springframework.stereotype.Service;
import org.springframework.security.access.prepost.PreAuthorize;
@Service
public class MyService {
@PreAuthorize("hasRole('ADMIN')")
public String adminAccess() {
return "Admin Access Granted";
}
@PreAuthorize("hasRole('USER')")
public String userAccess() {
return "User Access Granted";
}
@PreAuthorize("hasRole('USER') and hasRole('ADMIN')")
public String adminAndUserAccess() {
return "Admin and User Access Granted";
}
@PreAuthorize("#username == authentication.name")
public String accessOwnProfile(String username) {
return "Accessing own profile: " + username;
}
}
2. @Secured ব্যবহার করা
@Secured সরাসরি রোল নির্ধারণের জন্য ব্যবহৃত হয়। এটি অপেক্ষাকৃত সহজ অথোরাইজেশন প্রয়োজন হলে ব্যবহৃত হয়।
কনফিগারেশন
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
@Configuration
@EnableMethodSecurity(securedEnabled = true) // Enable @Secured annotation
public class SecurityConfig {
// No specific method-level security configuration needed.
}
মেথড উদাহরণ
import org.springframework.stereotype.Service;
import org.springframework.security.access.annotation.Secured;
@Service
public class MyService {
@Secured("ROLE_ADMIN")
public String adminAccess() {
return "Admin Access Granted";
}
@Secured("ROLE_USER")
public String userAccess() {
return "User Access Granted";
}
@Secured({"ROLE_USER", "ROLE_ADMIN"})
public String adminAndUserAccess() {
return "Admin and User Access Granted";
}
}
Spring Security Context-এ রোল এবং অথোরিটি ব্যবস্থাপনা
In-Memory Authentication উদাহরণ
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class UserConfig {
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER") // ROLE_USER হবে
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("admin")
.roles("ADMIN") // ROLE_ADMIN হবে
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
3. Controller স্তরে @PreAuthorize এবং @Secured
Controller উদাহরণ
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.annotation.Secured;
@RestController
public class MyController {
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String adminPage() {
return "Welcome Admin!";
}
@GetMapping("/user")
@Secured("ROLE_USER")
public String userPage() {
return "Welcome User!";
}
@GetMapping("/profile")
@PreAuthorize("#username == authentication.name")
public String profile(@RequestParam String username) {
return "Welcome to your profile, " + username;
}
}
4. @PreAuthorize এর শক্তিশালী স্পেলিং উদাহরণ
উন্নত অথোরাইজেশন
@PreAuthorize("hasAuthority('WRITE_PRIVILEGE') and hasRole('ADMIN')")
public String adminWriteAccess() {
return "Admin Write Access Granted";
}
@PreAuthorize("hasAuthority('READ_PRIVILEGE') or hasRole('USER')")
public String userOrReadAccess() {
return "User or Read Access Granted";
}
উপসংহার
- @PreAuthorize: জটিল অথোরাইজেশন লজিক প্রয়োগের জন্য ব্যবহার করা হয়।
- @Secured: সহজ এবং নির্দিষ্ট রোল ভিত্তিক অথোরাইজেশনের জন্য কার্যকর।
আপনার প্রয়োজন অনুযায়ী এই অ্যানোটেশনগুলো ব্যবহার করতে পারেন। @PreAuthorize জটিল লজিক এবং স্পেলিং ব্যবহারের জন্য আরও শক্তিশালী এবং কার্যকর।
স্প্রিং সিকিউরিটিতে Role-Based Authorization এবং Permission-Based Authorization ব্যবহার করে সুনির্দিষ্ট অ্যাক্সেস নিয়ন্ত্রণ সহজেই বাস্তবায়ন করা যায়। নিচে দুটি কৌশলের জন্য উদাহরণসহ সম্পূর্ণ ব্যাখ্যা দেওয়া হলো:
১. Role-Based Authorization
কাজের মূলনীতি:
- ব্যবহারকারীকে বিভিন্ন Role (যেমন
ROLE_USER,ROLE_ADMIN) দেওয়া হয়। - সুনির্দিষ্ট পেজ বা API অ্যাক্সেস করার জন্য রোল যাচাই করা হয়।
উদাহরণ: Role-Based Authorization
Step 1: Maven/Gradle Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Step 2: Security Configuration
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN") // Role-based access
.requestMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated()
)
.formLogin()
.and()
.logout().permitAll();
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Step 3: User Configuration (In-Memory User Store)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class UserConfig {
@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder.encode("admin"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
Step 4: Controller
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RoleController {
@GetMapping("/user/home")
public String userHome() {
return "Welcome to User Home";
}
@GetMapping("/admin/home")
public String adminHome() {
return "Welcome to Admin Home";
}
}
২. Permission-Based Authorization
কাজের মূলনীতি:
- প্রতিটি ব্যবহারকারীর নির্দিষ্ট Permission (যেমন
READ_PRIVILEGE,WRITE_PRIVILEGE) দেওয়া হয়। - ব্যবহৃত রিসোর্সে অ্যাক্সেস অনুমোদনের জন্য পারমিশন যাচাই করা হয়।
উদাহরণ: Permission-Based Authorization
Step 1: Security Configuration
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/read").hasAuthority("READ_PRIVILEGE") // Permission-based access
.requestMatchers("/write").hasAuthority("WRITE_PRIVILEGE")
.anyRequest().authenticated()
)
.formLogin()
.and()
.logout().permitAll();
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Step 2: Custom UserDetailsService
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.Arrays;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if ("reader".equals(username)) {
return new User(
"reader",
new BCryptPasswordEncoder().encode("password"),
Arrays.asList(new SimpleGrantedAuthority("READ_PRIVILEGE"))
);
} else if ("writer".equals(username)) {
return new User(
"writer",
new BCryptPasswordEncoder().encode("password"),
Arrays.asList(
new SimpleGrantedAuthority("READ_PRIVILEGE"),
new SimpleGrantedAuthority("WRITE_PRIVILEGE")
)
);
} else {
throw new UsernameNotFoundException("User not found");
}
}
}
Step 3: Controller
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PermissionController {
@GetMapping("/read")
public String readAccess() {
return "You have read access!";
}
@GetMapping("/write")
public String writeAccess() {
return "You have write access!";
}
}
উপসংহার
| বৈশিষ্ট্য | Role-Based Authorization | Permission-Based Authorization |
|---|---|---|
| অ্যাক্সেস কন্ট্রোল স্তর | সম্পূর্ণ রোল দ্বারা নিয়ন্ত্রিত | সুনির্দিষ্ট পারমিশন দ্বারা নিয়ন্ত্রিত |
| ব্যবহারকারীর নিয়ন্ত্রণ | সাধারণ এবং সীমিত নিয়ন্ত্রণ | আরও সূক্ষ্ম (Fine-Grained) নিয়ন্ত্রণ |
| উদাহরণ | hasRole("ADMIN") | hasAuthority("WRITE_PRIVILEGE") |
উপসংহার:
- Role-Based Authorization সহজ এবং দ্রুত বাস্তবায়নের জন্য কার্যকর।
- Permission-Based Authorization যখন জটিল এবং সূক্ষ্ম নিয়ন্ত্রণ প্রয়োজন হয় তখন প্রয়োজনীয়।
আপনার প্রজেক্টের প্রয়োজন অনুযায়ী এই দুইটি পদ্ধতির মধ্যে যেকোনো একটি বা উভয় একসাথে ব্যবহার করতে পারেন।
Read more